#pragma once

#include "mysql.hpp"
#include "blog.hxx"
#include "blog-odb.hxx"
#include <boost/date_time/posix_time/posix_time.hpp>
#include <sstream>
#include <algorithm>

namespace zhiang {

class BlogTable {
public:
    using ptr = std::shared_ptr<BlogTable>;
    BlogTable() {}
    BlogTable(const std::shared_ptr<odb::core::database>& db) :_db(db) {}
    // 插入博客
    bool insert(Blog& blog) {
        odb::transaction trans(_db->begin());
        try {
            _db->persist(blog);
            trans.commit();
        } catch(std::exception& e) {
            LOG_ERROR("插入blog-title[{}]数据失败：{}", blog.title(), e.what());
            trans.rollback();
            return false;
        }
        return true;
    }
    // 查找博客
    std::shared_ptr<Blog> find(const std::string& blog_id) {
        odb::transaction trans(_db->begin());
        std::shared_ptr<Blog> blog;
        try {               
            using query = odb::query<Blog>;
            using result = odb::result<Blog>;
            blog.reset(_db->query_one<Blog>(query::blog_id == blog_id));
            trans.commit();
        } catch(std::exception& e) {
            LOG_ERROR("查询blog数据-> [{}] ->失败：{}", blog_id, e.what());
            trans.rollback();
            return nullptr;
        }
        return blog;
    }
    // 查找博客
    std::vector<Blog> find(const std::vector<std::string>& id_list) {
        std::vector<Blog> ret;
        odb::transaction trans(_db->begin());
        try {               
            using query = odb::query<Blog>;
            using result = odb::result<Blog>;
            
            if (id_list.empty()) {
                trans.commit();
                return ret;
            }
            
            std::string condition = "blog_id in (";
            for (const auto& id : id_list) {
                condition += "'" + id + "',";
            }
            condition.pop_back(); // 移除最后一个逗号
            condition.push_back(')');
            
            result r(_db->query<Blog>(condition)); 
            for (result::iterator i(r.begin()); i != r.end(); ++i) { 
                ret.push_back(*i);
            }
            trans.commit();
        } catch(std::exception& e) {
            LOG_ERROR("批量查询blog数据失败：{}", e.what());
            trans.rollback();
        }
        return ret;
    }
    // 增加博客浏览量
    bool update(Blog& blog) {
        odb::transaction trans(_db->begin());
        try {
            _db->update(blog);
            trans.commit();
        } catch(std::exception& e) {
            LOG_DEBUG("插入blog-title[{}]数据失败：{}", blog.title(), e.what());
            trans.rollback();
            return false;
        }
        return true;
    }
    // 删除博客
    bool remove(const std::string& blog_id) {
        odb::transaction trans(_db->begin());
        try {
            using query = odb::query<Blog>;
            using result = odb::result<Blog>;
            _db->erase_query<Blog>(query::blog_id == blog_id);
            trans.commit();
        } catch(std::exception& e) {
            LOG_ERROR("删除blog数据-> [{}] ->失败：{}", blog_id, e.what());
            trans.rollback();
            return false;
        }
        return true;
    }
    // 获取博客列表
    std::vector<Blog> getBlogList(const std::string& uid) {
        odb::transaction trans(_db->begin());
        std::vector<Blog> ret;
        try {
            using query = odb::query<Blog>;
            using result = odb::result<Blog>;
            result r (_db->query<Blog>(query::user_id == uid)); 
            for (result::iterator i(r.begin()); i != r.end(); ++i) { 
                ret.push_back(*i);
            }
            trans.commit();
        } catch(std::exception& e) {
            LOG_ERROR("查询申请失败：{}", e.what());
            trans.rollback();
        }
        return ret;
    }

private:
    std::shared_ptr<odb::core::database> _db;
};

}